Skip to content

feat(rules): warn-version-readme-changelog-sync + bump 1.15.0 (defense-in-depth ↔ dojo-os)#22

Merged
lapc506 merged 3 commits into
mainfrom
andres/toolkit-rule-version-readme-sync
May 14, 2026
Merged

feat(rules): warn-version-readme-changelog-sync + bump 1.15.0 (defense-in-depth ↔ dojo-os)#22
lapc506 merged 3 commits into
mainfrom
andres/toolkit-rule-version-readme-sync

Conversation

@lapc506
Copy link
Copy Markdown
Collaborator

@lapc506 lapc506 commented May 14, 2026

Gap this closes

PR #21 closed the visible-version gap by reconstructing CHANGELOG.md and adding a Version: line to README.md. This PR adds the enforcement rule that prevents the gap from reopening on the next manifest bump — and dogfoods it by shipping itself via the new rule.

Without an automated rule, every future package.json / plugin.json / marketplace.json version bump would silently re-introduce the same drift PR #21 fixed.

What ships

1. New Tier 2 rule: warn-version-readme-changelog-sync

Triggers on: Write / Edit / MultiEdit to any of:

  • package.json
  • plugin.json (root-level)
  • marketplace.json (root-level)
  • .claude-plugin/plugin.json
  • .claude-plugin/marketplace.json

Match condition: content / new_string contains "version": "X.Y.Z"

Action: warn (non-blocking — the hook can only see one file at a time, so it nudges rather than enforces)

Bypass marker: version-readme-changelog-sync

11 new tests, all pass. Total: 32 rules / 210 tests (was 31 / 199).

2. Version bump to 1.15.0 across all four surfaces

File Before After
package.json 1.14.0 1.15.0
.claude-plugin/plugin.json 1.14.0 1.15.0
.claude-plugin/marketplace.json (top + nested) 1.14.0 1.15.0
README.md (`Version:` line) 1.14.0 1.15.0

3. CHANGELOG.md entry under ## [1.15.0] - 2026-05-14

Documents the new rule, the defense-in-depth pattern, and the dogfooding observation: this release ships via the rule it adds.

Defense-in-depth pattern (DOJ-4064 thesis)

This is the cross-repo half of a two-PR defense-in-depth implementation:

  • Toolkit level (this PR) — any consumer of the toolkit inherits the rule and gets the warning on every manifest bump, across every repo.
  • Repo level (parallel dojo-os PR) — local PostToolUse hook .claude/hooks/post-write-version-readme-sync.sh enforces the same invariant in dojo-os even if this toolkit isn't installed.

Both layers catch the same drift; neither alone is sufficient.

Sister PR in dojo-os: `andres/doj-readme-version-and-version-sync-hook` (opened in parallel — links back here in its body).

Stack note

This PR is stacked on top of PR #21 (`andres/toolkit-readme-version-and-changelog`), which adds the README `Version:` line and reconstructs CHANGELOG.md. PR #21 must merge first; this PR then auto-rebases onto `main`.

Commits (atomic)

  1. `feat(rules): add warn-version-readme-changelog-sync Tier 2 rule` (5dd0a67)
  2. `chore: bump to 1.15.0 across manifests + README` (c9469f0)
  3. `docs(changelog): add 1.15.0 entry (dogfooding the new rule)` (babb67e)

Verification

  • `npm run build-rules` → `Generated rules.json (32 rules)` ✓
  • `npm run test-hooks` → `Results: 210 / 210 passed` ✓
  • All four version surfaces align at 1.15.0 ✓

Hard constraints honoured

  • No --no-verify on any commit (let lefthook run).
  • Three atomic commits as specified.
  • No new Linear issue (preventive infrastructure).
  • Self-demonstrating: this PR's own files would trigger the rule it ships.

DO NOT MERGE

Andrés will review and merge. HITL gate.

Created by Claude Code on behalf of @andres.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 14, 2026

Greptile Summary

This PR adds a new Tier 2 warn-version-readme-changelog-sync hook rule that fires whenever a version manifest (package.json, plugin.json, or marketplace.json) is written with a semver "version" field, nudging the agent to keep README.md and CHANGELOG.md in sync. It also bumps all four version surfaces to 1.15.0 and ships the reconstructed CHANGELOG.md established in the stacked PR #21.

  • New rule (hooks/rules/rules.yaml + rules.json): pattern-matches manifest file paths and \"version\": \"X.Y.Z\" content; emits a non-blocking warn with a workflow suggestion; 11 tests added.
  • Version bump: package.json, .claude-plugin/plugin.json, and .claude-plugin/marketplace.json all aligned to 1.15.0; README.md header line updated to match.
  • CHANGELOG.md: new file with reconstructed history from 1.1.0 through 1.15.0, including the 1.15.0 entry documenting the dogfooding observation.

Path to 5/5 Confidence

1. Fix the bypass instruction for JSON manifest fileshooks/rules/rules.yaml and hooks/rules/rules.json, message: block of warn-version-readme-changelog-sync. Remove the sentence suggesting # hook-bypass: as an inline comment inside a JSON file. JSON has no comment syntax; following that instruction literally corrupts the manifest. Replace with guidance that is JSON-safe (e.g., describe only the tool-call-level bypass mechanism, or a separate-commit strategy).

2. Unify the bypass comment syntax — the message: field uses # (shell-style) but the allows-bypass-marker test case uses // (JS-style). Pick one and make both consistent. The framework schema example uses //.

3. Add the missing [1.15.0] reference link and fix [Unreleased]CHANGELOG.md line 228. Insert [1.15.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.15.0 between [Unreleased] and [1.14.0], and update the [Unreleased] compare base from v1.14.0 to v1.15.0. A suggestion block is already attached inline.

Confidence Score: 3/5

The manifest bumps and README/CHANGELOG changes are safe; the bypass instructions in the new rule's warning message would corrupt a JSON manifest if followed literally.

The new rule's warning text directs users to embed a # hook-bypass: comment inside package.json (or the other JSON manifests), but JSON has no comment syntax. Following that instruction as written would write invalid JSON, breaking npm install and every tool that reads the manifest. The test case allows-bypass-marker reinforces the broken approach and also uses // while the prose says #. The CHANGELOG footer is additionally missing the [1.15.0] reference link and has a stale [Unreleased] compare URL pointing at v1.14.0.

hooks/rules/rules.yaml and the generated hooks/rules/rules.json — the bypass guidance in the message field needs to drop the JSON-comment approach and only describe the tool-call-level bypass or a JSON-safe alternative.

Important Files Changed

Filename Overview
hooks/rules/rules.yaml Adds warn-version-readme-changelog-sync Tier 2 rule with 11 tests; bypass instruction for JSON manifest files recommends embedding a comment syntax that is invalid in JSON, and message text (#) and test case (//) use different comment styles.
hooks/rules/rules.json Generated file mirrors the new YAML rule correctly; same bypass-in-JSON issue inherited from the source YAML.
CHANGELOG.md New file with reconstructed history; [1.15.0] reference link is missing from the footer and [Unreleased] still points to v1.14.0 instead of v1.15.0.
README.md Adds Version: 1.15.0 line with links to CHANGELOG and Marketplace — clean, no issues.
package.json Version bumped from 1.12.0 to 1.15.0 (spanning the stacked PR #21 delta); no issues.
.claude-plugin/plugin.json Version bumped from 1.11.0 to 1.15.0; no issues.
.claude-plugin/marketplace.json Both top-level and nested plugin version bumped from 1.12.0 to 1.15.0; no issues.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Claude writes/edits manifest file] --> B{file_path matches\npackage.json /\nplugin.json /\nmarketplace.json?}
    B -- No --> Z[Pass — no action]
    B -- Yes --> C{content contains\n'version': 'X.Y.Z'?}
    C -- No --> Z
    C -- Yes --> D{bypass marker\npresent in any\ntool_input field?}
    D -- Yes --> Z
    D -- No --> E[WARN: version-readme-changelog-sync\nexit 0 message to stderr]
    E --> F[Agent nudged to update\nREADME.md Version line\n+ CHANGELOG.md entry]
Loading
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
hooks/rules/rules.yaml:2222-2236
**Bypass instruction produces invalid JSON**

The warning message tells users to add `"# hook-bypass: version-readme-changelog-sync"` as a comment near the version field in `package.json`, `plugin.json`, or `marketplace.json`. JSON has no comment syntax — embedding either `#` or `//` style comments produces a file that fails JSON parsing, which would break `npm install`, CI pipelines, and any tool reading the manifest. The test case `allows-bypass-marker` reinforces the same invalid pattern (using `//` while the message text says `#` — a second inconsistency). The bypass message should drop the embedded-comment suggestion entirely for JSON targets and only describe the tool-call–level mechanism ("pass it on the Write call"), or document a safe alternative.

### Issue 2 of 2
CHANGELOG.md:228-229
The `[1.15.0]` reference link is missing from the footer, so the `## [1.15.0]` heading in rendered Markdown is not a clickable link. The `[Unreleased]` compare URL also still points to `v1.14.0` instead of the just-released `v1.15.0`.

```suggestion
[Unreleased]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/compare/v1.15.0...HEAD
[1.15.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.15.0
[1.14.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.14.0
```

Reviews (1): Last reviewed commit: "docs(changelog): add 1.15.0 entry (dogfo..." | Re-trigger Greptile

Comment thread hooks/rules/rules.yaml
Comment on lines +2222 to +2236
input:
tool_input:
file_path: 'CHANGELOG.md'
content: '## [1.15.0] - 2026-05-14'
expected_exit: 0
- name: allows-bypass-marker
input:
tool_input:
file_path: 'package.json'
content: |
{
"version": "1.15.0"
// hook-bypass: version-readme-changelog-sync
}
expected_exit: 0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Bypass instruction produces invalid JSON

The warning message tells users to add "# hook-bypass: version-readme-changelog-sync" as a comment near the version field in package.json, plugin.json, or marketplace.json. JSON has no comment syntax — embedding either # or // style comments produces a file that fails JSON parsing, which would break npm install, CI pipelines, and any tool reading the manifest. The test case allows-bypass-marker reinforces the same invalid pattern (using // while the message text says # — a second inconsistency). The bypass message should drop the embedded-comment suggestion entirely for JSON targets and only describe the tool-call–level mechanism ("pass it on the Write call"), or document a safe alternative.

Prompt To Fix With AI
This is a comment left during a code review.
Path: hooks/rules/rules.yaml
Line: 2222-2236

Comment:
**Bypass instruction produces invalid JSON**

The warning message tells users to add `"# hook-bypass: version-readme-changelog-sync"` as a comment near the version field in `package.json`, `plugin.json`, or `marketplace.json`. JSON has no comment syntax — embedding either `#` or `//` style comments produces a file that fails JSON parsing, which would break `npm install`, CI pipelines, and any tool reading the manifest. The test case `allows-bypass-marker` reinforces the same invalid pattern (using `//` while the message text says `#` — a second inconsistency). The bypass message should drop the embedded-comment suggestion entirely for JSON targets and only describe the tool-call–level mechanism ("pass it on the Write call"), or document a safe alternative.

How can I resolve this? If you propose a fix, please make it concise.

Comment thread CHANGELOG.md
Comment on lines +228 to +229
[Unreleased]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/compare/v1.14.0...HEAD
[1.14.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.14.0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The [1.15.0] reference link is missing from the footer, so the ## [1.15.0] heading in rendered Markdown is not a clickable link. The [Unreleased] compare URL also still points to v1.14.0 instead of the just-released v1.15.0.

Suggested change
[Unreleased]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/compare/v1.14.0...HEAD
[1.14.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.14.0
[Unreleased]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/compare/v1.15.0...HEAD
[1.15.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.15.0
[1.14.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.14.0
Prompt To Fix With AI
This is a comment left during a code review.
Path: CHANGELOG.md
Line: 228-229

Comment:
The `[1.15.0]` reference link is missing from the footer, so the `## [1.15.0]` heading in rendered Markdown is not a clickable link. The `[Unreleased]` compare URL also still points to `v1.14.0` instead of the just-released `v1.15.0`.

```suggestion
[Unreleased]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/compare/v1.15.0...HEAD
[1.15.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.15.0
[1.14.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.14.0
```

How can I resolve this? If you propose a fix, please make it concise.

lapc506 and others added 3 commits May 14, 2026 09:09
Warns when a version manifest (package.json, plugin.json, marketplace.json,
or their .claude-plugin/ namespaced variants) is being bumped without a
parallel update to README.md + CHANGELOG.md.

This closes the gap PR #21 exposed: the toolkit shipped 1.1.0 -> 1.14.0
with no visible version surface (no README line, no CHANGELOG, no git tags).
Without an enforcement rule, the same drift will reappear on the next bump.

Pattern (DOJ-4064 three-layer drift thesis, Cure 4 - PreToolUse hooks):

  - Triggers on Write/Edit/MultiEdit to package.json, plugin.json,
    marketplace.json, .claude-plugin/plugin.json, .claude-plugin/marketplace.json
  - Detects new `"version": "X.Y.Z"` field in the written content / new_string
  - Warns the agent to update README.md "Version:" line + CHANGELOG.md entry
    in the same change
  - Tier 2 (warn, non-blocking) - hook cannot see other files in the diff,
    so it nudges rather than enforces
  - Bypass marker: version-readme-changelog-sync

Sister enforcement (defense-in-depth): the dojo-os repo ships its own
PostToolUse hook (.claude/hooks/post-write-version-readme-sync.sh) that
catches the same drift locally even when the toolkit isn't installed.

11 new tests, all pass. Total rules: 32 (was 31).

Created by Claude Code on behalf of @andres.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Coordinated bump across the four version surfaces:
  - package.json                       1.14.0 -> 1.15.0
  - .claude-plugin/plugin.json         1.14.0 -> 1.15.0
  - .claude-plugin/marketplace.json    1.14.0 -> 1.15.0 (top + nested)
  - README.md "Version: ..." line      1.14.0 -> 1.15.0

This is the first bump that dogfoods the warn-version-readme-changelog-sync
rule shipped in the prior commit on this branch: every manifest write would
now warn about the README/CHANGELOG update requirement. README is being
updated in this same commit; CHANGELOG entry follows in the next commit.

Created by Claude Code on behalf of @andres.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds the 1.15.0 section to CHANGELOG.md immediately above the existing
1.14.0 entry, documenting:

  - The new warn-version-readme-changelog-sync Tier 2 rule (32 rules total)
  - The defense-in-depth pattern (toolkit + dojo-os parallel PRs)
  - The dogfooding observation: this release ships via the rule it adds

This is the third atomic commit of the PR:
  1. feat(rules): add the rule (commit 5dd0a67)
  2. chore: bump to 1.15.0 across manifests + README (commit c9469f0)
  3. docs(changelog): add 1.15.0 entry (this commit)

Together they demonstrate the full discipline the rule enforces:
manifest + README + CHANGELOG all updated in lockstep within the same PR.

Created by Claude Code on behalf of @andres.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@lapc506 lapc506 force-pushed the andres/toolkit-rule-version-readme-sync branch 2 times, most recently from babb67e to 06c185f Compare May 14, 2026 15:09
@lapc506 lapc506 merged commit 9b4516d into main May 14, 2026
2 checks passed
@lapc506 lapc506 deleted the andres/toolkit-rule-version-readme-sync branch May 14, 2026 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant